#include "../internal/cuCoreLib.h"
#include "cuAssert.h"

#ifdef USE_ZEL_ASSERTIONS
const char* z3d::core::Assert::msDebugPrompt = "\n\nDo you want to debug?";
const size_t z3d::core::Assert::msDebugPromptLength = strlen(z3d::core::Assert::msDebugPrompt);
const char* z3d::core::Assert::msMessagePrefix = "\nAssert failed at %s(%d):\n";
#endif //USE_ZEL_ASSERTIONS

#ifdef ZEL_USE_ASSERT_WRITE_TO_MESSAGE_BOX
const char* z3d::core::Assert::m_messageBoxTitle = "Assert Failed";
#endif //ZEL_USE_ASSERT_WRITE_TO_MESSAGE_BOX

#ifdef ZEL_USE_ASSERT_WRITE_TO_MESSAGE_BOX
#include <Windows.h>
#include <intrin.h>
#endif //ZEL_USE_ASSERT_WRITE_TO_MESSAGE_BOX


#ifdef USE_ZEL_ASSERTIONS
z3d::core::Assert::Assert( bool condition, const char* file, int line, const char* format,... )
{
	if (condition)
	{
		// The assertion is satisfied.
		return;
	}
	const uint32_t MAX_MESSAGE_BYTES = 1024;
	// The message prefix.
	char message[MAX_MESSAGE_BYTES];
	const size_t maxPrefixBytes = MAX_MESSAGE_BYTES - msDebugPromptLength - 1;
	_snprintf(message, maxPrefixBytes, msMessagePrefix, file, line);

	// Append user-specified arguments.
	va_list arguments;
	va_start(arguments, format);
	size_t length = strlen(message);
	_vsnprintf(message + length, maxPrefixBytes - length, format, arguments);
	va_end(arguments);

#ifdef ZEL_USE_ASSERT_WRITE_TO_OUTPUT_WINDOW
	// Write the message to the output debug window.
	OutputDebugString(message);
#endif

#ifdef ZEL_USE_ASSERT_WRITE_TO_MESSAGE_BOX
	// Give the user a chance to break-and-debug, to continue, or to
	// terminate execution.
	strcat(message, msDebugPrompt);
	int selection = ::MessageBox(0, message,m_messageBoxTitle,
		MB_ICONERROR | MB_YESNOCANCEL | MB_APPLMODAL | MB_TOPMOST);

	switch (selection)
	{
	case IDYES:
		// Break and debug.
		__debugbreak();
		break;
	case IDNO:
		// Continue execution.
		break;
	case IDCANCEL:
	default:
		// Terminate execution.
		exit(0);
		break;
	}
#endif
}
#endif //USE_ZEL_ASSERTIONS
